﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace Code.DAL
{
    public class CreateCode
    {
        public string CreateProc(Table tb)
        {
            StringBuilder str = new StringBuilder(Code.Properties.Resources.Proc);
            str = Replace("tableName", tb.Name, str);
            str = Replace("author", Info.Author, str);
            str = Replace("date", DateTime.Now.ToString("yyyy-MM-dd"), str);
            //拼接添加和修改存储过程中的参数
            string temp = null;
            foreach (Column c in tb.Columns)
            {
                temp += "\t@" + c.Name + " " + getSQLType(c) + "," + System.Environment.NewLine;
            }
            temp = temp.Substring(0, temp.Length - 3);
            str = Replace("Add_Update_Parameter", temp, str);
            //替换insertParameter和insertValues参数
            string insertParameter = string.Empty;
            string insertValues = string.Empty;
            foreach (Column c in tb.Columns)
            {
                if (!c.IsIdentity)
                {
                    insertParameter += "[" + c.Name + "],";
                    insertValues += "@" + c.Name + ",";
                }
            }
            insertParameter = insertParameter.Substring(0, insertParameter.Length - 1);
            str = Replace("insertParameter", insertParameter, str);
            insertValues = insertValues.Substring(0, insertValues.Length - 1);
            str = Replace("insertValues", insertValues, str);
            //替换updateSet参数
            string updateSet = string.Empty;
            foreach (Column c in tb.Columns)
            {
                if (!c.IsIdentity)
                {
                    updateSet += "[" + c.Name + "]=@" + c.Name + ",";
                }
            }
            updateSet = updateSet.Substring(0, updateSet.Length - 1);
            str = Replace("updateSet", updateSet, str);
            //替换dicKey，和keyParameter参数
            string dicKey = string.Empty;
            string keyParameter = string.Empty;
            var lstCol= tb.Columns.Where(x => x.IsKey == true);
            foreach (var c in lstCol)
            {
                dicKey += "[" + c.Name + "]=@" + c.Name + " and ";
                if (c.IsKey)
                {
                    keyParameter += "\t@" + c.Name + " " + getSQLType(c) + "," + System.Environment.NewLine;
                }
            }
            dicKey = dicKey.Substring(0, dicKey.Length - 4);
            str = Replace("dicKey", dicKey, str);
            keyParameter = keyParameter.Substring(0, keyParameter.Length - 3);
            str = Replace("keyParameter", keyParameter, str);
            //替换keyname参数
            string keyName = string.Empty;
            Column colTemp = tb.Columns.Single(x => x.IsKey == true);
            keyName=colTemp.Name;
            str=Replace("keyName",keyName,str);
            return str.ToString();
        }

        public string CreateEntity(Table tb)
        {
            StringBuilder str = new StringBuilder(Code.Properties.Resources.Entity);
            str = Replace("EntityNamespace", Info.EntityNamespace, str);
            str = Replace("tableName", tb.Name, str);
            str = Replace("author", Info.Author, str);
            str = Replace("date", DateTime.Now.ToString("yyyy-MM-dd"), str);
            str = Replace("className", FirstCapital(tb.Name), str);
            string col = string.Empty;
            foreach(var c in tb.Columns)
            {
                col += "\t/// <summary>"+Environment.NewLine;
                col += "\t/// "+c.Desc+Environment.NewLine;
                col += "\t/// </summary>"+Environment.NewLine;
                col += "\tpublic "+GetColType(c) +" " +FirstCapital(c.Name)+Environment.NewLine;
                col += "\t{"+Environment.NewLine;
                col += "\t    get;"+Environment.NewLine;
                col += "\t    set;"+Environment.NewLine;
                col += "\t}"+Environment.NewLine;
                col += Environment.NewLine;
            }
            str = Replace("col", col, str);
            return str.ToString();
        }

        public string CreateIDAL(Table tb)
        {
            StringBuilder str = new StringBuilder(Code.Properties.Resources.IDAL);
            str = Replace("EntityNamespace", Info.EntityNamespace, str);
            str = Replace("EntityName", FirstCapital(tb.Name), str);
            str = Replace("author", Info.Author, str);
            str = Replace("date", DateTime.Now.ToString("yyyy-MM-dd"), str);
            str = Replace("IDALNamespace", Info.IDALNamespace, str);
            return str.ToString();
        }

        public string CreateDAL(Table tb)
        {
            StringBuilder str = new StringBuilder(Code.Properties.Resources.DAL);
            str= Replace("IDALNamespace", Info.IDALNamespace, str);
            str= Replace("EntityNamespace", Info.EntityNamespace, str);
            str = Replace("DALNamespace", Info.DALNamespace, str);
            str = Replace("ClassName", FirstCapital(tb.Name), str);
            str = Replace("author", Info.Author, str);
            str = Replace("date", DateTime.Now.ToString("yyyy-MM-dd"), str);
            //替换addTool参数
            string addTool = string.Empty;
            foreach (var c in tb.Columns)
            {
                addTool += "\t\ttool.AddSqlParameter(\"" + c.Name + "\"," + GetSQLDBType(c.Type) + " ," + c.Length.ToString() + ",t." +FirstCapital( c.Name)+");"+Environment.NewLine;
            }
            addTool = addTool.Substring(0, addTool.Length - 2);
            str = Replace("addTool", addTool, str);
            str = Replace("DB_CONN", Info.DB_CONN, str);
            str = Replace("LogName", Info.LogName, str);
            //替换deleteDic参数
            var temp = tb.Columns.Where(x => x.IsKey == true);
            string keyDic = string.Empty;
            string idDic = string.Empty;
            foreach(var c in temp)
            {
                keyDic += "\t\ttool.AddSqlParameter(\"" + c.Name + "\"," + GetSQLDBType(c.Type) + " ," + c.Length.ToString() + ",t." + FirstCapital(c.Name) + ");" + Environment.NewLine;
                idDic = "\t\ttool.AddSqlParameter(\"" + c.Name + "\"," + GetSQLDBType(c.Type) + " ," + c.Length.ToString() + ",id);";
            }
            keyDic = keyDic.Substring(0, keyDic.Length - 2);
            str = Replace("keyDic", keyDic, str);
           str=  Replace("idDic", idDic, str);
            string getElement = string.Empty;
            foreach (var c in tb.Columns)
            {
                getElement += "                    m." + FirstCapital(c.Name) + " = Tools.Get" + GetColType2(c) + "(reader[\"" + c.Name + "\"]);" + Environment.NewLine;
            }
            getElement = getElement.Substring(0, getElement.Length - 2);
            str = Replace("getElement", getElement, str);
            return str.ToString();
        }

        public string CreateIBaseBLL(Table tb)
        {
            StringBuilder str = new StringBuilder(Code.Properties.Resources.IBaseBLL);
            str = Replace("IBLLNamespace", Info.IBLLNamespace, str);
            str = Replace("author", Info.Author, str);
            str = Replace("date", DateTime.Now.ToString("yyyy-MM-dd"), str);
            return str.ToString();
        }

        public string CreateIBaseDAL(Table tb)
        {
            StringBuilder str = new StringBuilder(Code.Properties.Resources.IBaseDAL);
            str = Replace("IDALNamespace", Info.IDALNamespace, str); 
            str = Replace("author", Info.Author, str);
            str = Replace("date", DateTime.Now.ToString("yyyy-MM-dd"), str);
            return str.ToString();
        }

        public string CreateIBLL(Table tb)
        {
            StringBuilder str = new StringBuilder(Code.Properties.Resources.IBLL);
            str = Replace("EntityNamespace", Info.EntityNamespace, str);
            str = Replace("IBLLNamespace", Info.IBLLNamespace, str);
            str = Replace("ClassName", FirstCapital(tb.Name), str); 
            str = Replace("author", Info.Author, str);
            str = Replace("date", DateTime.Now.ToString("yyyy-MM-dd"), str);
            return str.ToString();
        }

        public string CreateBLL(Table tb)
        {
            StringBuilder str = new StringBuilder(Code.Properties.Resources.BLL);
            str = Replace("IBLLNamespace", Info.IBLLNamespace, str);
            str = Replace("EntityNamespace", Info.EntityNamespace, str);
            str = Replace("DALNamespace", Info.DALNamespace, str);
            str = Replace("IDALNamespace", Info.IDALNamespace, str);
            str = Replace("BLLNamespace", Info.BLLNamespace, str);
            str = Replace("ClassName", FirstCapital(tb.Name), str);
            str = Replace("lowwerName", FirstLowwer(tb.Name), str);
            str = Replace("author", Info.Author, str);
            str = Replace("date", DateTime.Now.ToString("yyyy-MM-dd"), str);
            return str.ToString();
        }

        public string CreateTools(Table tb)
        {
            StringBuilder str = new StringBuilder(Code.Properties.Resources.Tools);
            str = Replace("DALNamespace", Info.DALNamespace, str);
            return str.ToString();

        }

        public StringBuilder Replace(string oldStr, string newStr, StringBuilder strBuilder)
        {
            if (!oldStr.StartsWith("<%"))
            {
                oldStr = "<%" + oldStr;
            }
            if (!oldStr.EndsWith("%>"))
            {
                oldStr += "%>";
            }
            return strBuilder.Replace(oldStr, newStr);
        }

        private string getSQLType(Column c)
        {
            string[] strs = new string[] { "char", "nchar", "nvarchar", "varchar" };
            if (strs.Contains(c.Type))
            {
                return c.Type + "(" + c.Length.ToString() + ")";
            }
            else
            {
                return c.Type;
            }
        }

        /// <summary>
        /// 首字母大写
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public string FirstCapital(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return str;
            }
            string temp = str.Substring(0, 1);
            return temp.ToUpper()+str.Substring(1,str.Length-1);
        }

        private string FirstLowwer(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return str;
            }
            string temp = str.Substring(0, 1);
            return temp.ToLower() + str.Substring(1, str.Length - 1);
        }
        
        
        private string GetColType(Column col)
        {
            string[] strString = new string[] { "char", "nchar", "ntext", "nvarchar", "text", "varchar" };
            string[] strGuid = new string[] { "uniqueidentifier" };
            string[] strLong = new string[] { "bigint" };
            string[] strInt = new string[] { "int", "bit", "smallint", "tinyint" };
            string[] strDouble = new string[] { "Decimal", "float", "money", "real", "smallmoney"};
            string[] strDateTime = new string[] { "smalldatetime", "datetime" };
            string colName=col.Type.ToLower();
            if (strString.Contains(colName))
            {
                return "string";
            }
            if (strGuid.Contains(colName))
            {
                return "Guid?";
            }
            if (strLong.Contains(colName))
            {
                return "long?";
            }
            if (strInt.Contains(colName))
            {
                return "int?";
            }
            if (strDouble.Contains(colName))
            {
                return "double?";
            }
            if (strDateTime.Contains(colName))
            {
                return "DateTime?";
            }
            return "没有找到合适的类型";
        }

        private string GetColType2(Column col)
        {
            string[] strString = new string[] { "char", "nchar", "ntext", "nvarchar", "text", "varchar" };
            string[] strGuid = new string[] { "uniqueidentifier" };
            string[] strLong = new string[] { "bigint" };
            string[] strInt = new string[] { "int", "bit", "smallint", "tinyint" };
            string[] strDouble = new string[] { "Decimal", "float", "money", "real", "smallmoney" };
            string[] strDateTime = new string[] { "smalldatetime", "datetime" };
            string colName = col.Type.ToLower();
            if (strString.Contains(colName))
            {
                return "String";
            }
            if (strGuid.Contains(colName))
            {
                return "Guid";
            }
            if (strLong.Contains(colName))
            {
                return "Long";
            }
            if (strInt.Contains(colName))
            {
                return "Int";
            }
            if (strDouble.Contains(colName))
            {
                return "Double";
            }
            if (strDateTime.Contains(colName))
            {
                return "DateTime";
            }
            return "没有找到合适的类型";
        }

        private string GetSQLDBType(string str)
        {
            switch (str.ToLower())
            {
                case ("bigint"):
                    return "SqlDbType.BigInt"; 
                case("binary"):
                    return "SqlDbType.Binary";
                case("bit"):
                    return "SqlDbType.Bit";
                case("char"):
                    return "SqlDbType.Char";
                case("datetime"):
                    return "SqlDbType.DateTime";
                case("decimal"):
                    return "SqlDbType.Decimal";
                case("float"):
                    return "SqlDbType.Float";
                case("image"):
                    return "SqlDbType.Image";
                case("int"):
                    return "SqlDbType.Int";
                case ("money"):
                    return "SqlDbType.Money";
                case("nchar"):
                    return "SqlDbType.NChar";
                case("ntext"):
                    return "SqlDbType.NText";
                case("nvarchar"):
                    return "SqlDbType.NVarChar";
                case("real"):
                    return "SqlDbType.Real";
                case("smalldatetime"):
                    return "SqlDbType.SmallDateTime";
                case("smallint"):
                    return "SqlDbType.SmallInt";
                case("smallmoney"):
                    return "SqlDbType.SmallMoney";
                case("text"):
                    return "SqlDbType.Text";
                case("timestamp"):
                    return "SqlDbType.Timestamp";
                case("tinyint"):
                    return "SqlDbType.TinyInt";
                case("varbinary"):
                    return "SqlDbType.VarBinary";
                case("varchar"):
                    return "SqlDbType.VarChar";
                case("uniqueidentifier"):
                    return "SqlDbType.UniqueIdentifier";
                default:
                    return "没有找到数据类型";
            }

        }
    }
}
